
package com.jf.cloud.platform.service.impl;

import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.jf.cloud.common.bean.AliQuick;
import com.jf.cloud.common.bean.Quick100;
import com.jf.cloud.common.bean.QuickBird;
import com.jf.cloud.common.bean.SwitchBaseModel;
import com.jf.cloud.common.cache.constant.ConfigCacheNames;
import com.jf.cloud.common.constant.Constant;
import com.jf.cloud.common.util.Json;
import com.jf.cloud.platform.mapper.SysConfigMapper;
import com.jf.cloud.platform.model.SysConfig;
import com.jf.cloud.platform.service.SysConfigService;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 系统配置信息表
 *
 * @author zz
 * @date 2020-12-23 16:27:57
 */
@Service
public class SysConfigServiceImpl implements SysConfigService {

    @Resource
    private SysConfigMapper sysConfigMapper;

    @Override
    @Caching(evict = {
            @CacheEvict(cacheNames= ConfigCacheNames.SYS_CONFIG_OBJECT,key="#key"),
            @CacheEvict(cacheNames= ConfigCacheNames.SYS_CONFIG,key="#key")
    })
    public void updateValueByKey(String key, String value) {
//        sysConfigMapper.updateValueByKey(key, value);
    }

    @Override
    public void deleteBatch(Long[] ids) {
//        sysConfigMapper.deleteBatch(ids);
    }

    @Override
    @Cacheable(cacheNames = ConfigCacheNames.SYS_CONFIG_VALUE, key = "#key")
    public String getValue(String key) {
        SysConfig config = sysConfigMapper.queryByKey(key);
        return config == null ? null : config.getParamValue();
    }

    @Override
    @Caching(evict = {
            @CacheEvict(cacheNames = ConfigCacheNames.SYS_CONFIG_OBJECT,key="#key"),
            @CacheEvict(cacheNames = ConfigCacheNames.SYS_CONFIG_VALUE,key="#key"),
            @CacheEvict(cacheNames = ConfigCacheNames.SYS_CONFIG,key="#key")
    })
    public void removeSysConfig(String key) {
    }

    @Override
    @Caching(evict = {
            @CacheEvict(cacheNames = ConfigCacheNames.SYS_CONFIG_OBJECT,key="#sysConfig.paramKey"),
            @CacheEvict(cacheNames = ConfigCacheNames.SYS_CONFIG_VALUE,key="#sysConfig.paramKey"),
            @CacheEvict(cacheNames = ConfigCacheNames.SYS_CONFIG,key="#sysConfig.paramKey")
    })
    public void saveOrUpdateSysConfig(SysConfig sysConfig) {
        if (sysConfigMapper.countByKey(sysConfig.getParamKey()) > 0) {
            sysConfigMapper.update(sysConfig);
        }else{
            sysConfigMapper.save(sysConfig);
        }
    }

    @Override
    @Cacheable(cacheNames = ConfigCacheNames.SYS_CONFIG, key = "#key")
    public SysConfig getByKey(String key) {
        return sysConfigMapper.queryByKey(key);
    }

    @Override
    public List<String> saveDeliveryConfig(SysConfig sysConfig) {
        // 失效的缓存keys
        List<String> invalidKeys = new ArrayList<>();
        SwitchBaseModel switchBaseModel = Json.parseObject(sysConfig.getParamValue(), SwitchBaseModel.class);
        if (BooleanUtil.isTrue(switchBaseModel.getIsOpen())) {
            // 关闭其他物流查询配置
            if (!Objects.equals(sysConfig.getParamKey(), Constant.ALI_QUICK_CONFIG)) {
                // 关闭阿里快递查询
                this.closeSwitch(Constant.ALI_QUICK_CONFIG, AliQuick.class, invalidKeys);
            }
            if (!Objects.equals(sysConfig.getParamKey(), Constant.QUICK100_CONFIG)) {
                // 关闭快递100查询
                this.closeSwitch(Constant.QUICK100_CONFIG, Quick100.class, invalidKeys);
            }
            if (!Objects.equals(sysConfig.getParamKey(), Constant.QUICKBIRD_CONFIG)) {
                // 关闭快递鸟查询
                this.closeSwitch(Constant.QUICKBIRD_CONFIG, QuickBird.class, invalidKeys);
            }
            // 如果有新增的物流查询配置，在这里补上关闭的代码
        }
        // 保存当前物流查询配置
        this.saveOrUpdateSysConfig(sysConfig);
        invalidKeys.add(sysConfig.getParamKey());
        return invalidKeys;
    }

    /**
     * 关闭激活开关
     * @param key 配置项key
     * @param clazz 继承了SwitchBaseModel的类
     * @param invalidKeys 缓存失效的配置集合
     * @param <T>
     */
    public <T> void closeSwitch(String key, Class<T> clazz, List<String> invalidKeys) {
        if (!SwitchBaseModel.class.isAssignableFrom(clazz)) {
            // 不是配置开关属性类的子类不能调用该方法
            return;
        }
        T valueObj = this.getSysConfigObject(key, clazz);
        if (Objects.isNull(valueObj)) {
            // 当前配置在数据库不存在
            return;
        }
        try {
            PropertyDescriptor pd = new PropertyDescriptor("isOpen", clazz);
            Method readMethod = pd.getReadMethod();
            if (BooleanUtil.isFalse((Boolean) readMethod.invoke(valueObj))) {
                // isOpen已经是关闭状态，直接返回
                return;
            }
            Method writeMethod = pd.getWriteMethod();
            // 关闭当前配置
            writeMethod.invoke(valueObj, false);
        } catch (Exception e) {
            return;
        }
        String str = Json.toJsonString(valueObj);
        sysConfigMapper.updateValueByKey(key, str);
        invalidKeys.add(key);
    }

    @Override
    @Cacheable(cacheNames = ConfigCacheNames.SYS_CONFIG_OBJECT,key="#key")
    @SuppressWarnings("unchecked")
    public <T> T  getSysConfigObject(String key, Class<T> clazz) {
        String value = getValue(key);
        if (StrUtil.isBlank(value)) {
            return null;
        }

        if(Objects.equals(String.class,clazz)){
            return (T)value;
        }else{
            return Json.parseObject(value, clazz);
        }
    }
}
